﻿using System.Collections.Generic;
using System.Linq;
using System.Windows.Ink;
using BitsOfStuff.MyActions;

namespace BitsOfStuff
{
    /// <summary>
    /// This class provide choosing between two actions
    /// </summary>
    public class ActionArbitr
    {
        // ReSharper disable UnusedMember.Local
        private List<MyShowAction> _actions;
        // ReSharper restore UnusedMember.Local
        private readonly MyShapeRecognize _myShapeRecognize;

        /// <summary>
        /// Constructor of action a arbiter
        /// </summary>
        /// <param name="shapeRecognize">reference to shape recognizer for some add info about shape</param>
        /// <param name="charRecognizer">refernce to char recognizer for some add info about analyzed strokes</param>
        // ReSharper disable UnusedParameter.Local
        public ActionArbitr(MyShapeRecognize shapeRecognize, MyCharRecognizer charRecognizer)
        // ReSharper restore UnusedParameter.Local
        {
            _myShapeRecognize = shapeRecognize;
            // _charRecognizer = charRecognizer;
        }

        // ReSharper disable RedundantNameQualifier
        private MyAction choose(List<MyActions.MyShowAction> actions)
        // ReSharper restore RedundantNameQualifier
        {
            // ReSharper disable RedundantNameQualifier
            return actions.Count == 2 ? choosBetween2Actions(actions) : new MyActions.MyCharNotFoundAction();
            // ReSharper restore RedundantNameQualifier
        }

        /// <summary>
        /// Main action that choosing between aciton in list
        /// </summary>
        /// <param name="actions">action for choose</param>
        /// <returns>choosen action</returns>
        public MyAction choose(List<MyAction> actions)
        {
            if (actions.Any(myAction => !(myAction is MyShowAction)))
            {
                return new MyDoNothingAction();
            }
            var showActions = actions.Cast<MyShowAction>().ToList();

            return choose(showActions);
        }

        private bool isItUoverV()
        {
            if (_myShapeRecognize.getSelectionPoint().Exists(point => point is CurvePoint))
                return true;
            return false;
        }

        private bool isItBoverD()
        {
            if (_myShapeRecognize.getSelectionPoint().Exists(point => point is CordnerPoint))
                return true;
            return false;
        }

        private bool isItOover0()
        {
            //Stroke _stroke = _myShapeRecognize.getLastStroke();

            //double height = _stroke.StylusPoints.Max(point => point.Y) - _stroke.StylusPoints.Min(point => point.Y);
            //double weigth = _stroke.StylusPoints.Max(point => point.X) - _stroke.StylusPoints.Min(point => point.X);

            //double ratio = height / weigth;

            //if (ratio < MyParameters.Oover0Ratio)
            //{
            //    return true;
            //}
            //return false;
            return false;
        }

        private bool isItLoverH()
        {
            if (_myShapeRecognize.getSelectionPoint().Count == 3)
                return true;
            return false;
        }

        private bool isCover9()
        {
            var lastStroke = _myShapeRecognize.getLastSequence();
            if (lastStroke.LastOrDefault() > 3)
                return false;
            return true;
        }

        private MyAction choosBetween2Actions(List<MyShowAction> actions)
        {
            MyShowAction a =
                actions.FirstOrDefault(
                    action =>
                    action.getChar() == 'U' || action.getChar() == 'O' || action.getChar() == 'B' ||
                    action.getChar() == 'L' || action.getChar() == 'C');
            MyShowAction b =
                actions.FirstOrDefault(
                    action =>
                    action.getChar() == 'V' || action.getChar() == '0' || action.getChar() == 'D' ||
                    action.getChar() == 'H' || action.getChar() == '9');
            MyShowAction c = actions.FirstOrDefault(action => action.getChar() == 'S');

            if (a != null && a.getChar() == 'U')
            {
                if (isItUoverV())
                    return a;
                return b;
            }

            if (a != null && a.getChar() == 'O')
            {
                if (isItOover0())
                    return a;
                return b;
            }

            if (a != null && a.getChar() == 'B')
            {
                if (isItBoverD())
                    return a;
                return b;
            }

            if (a != null && a.getChar() == 'L')
            {
                if (isItLoverH())
                    return a;
                return b;
            }

            if (a != null && a.getChar() == 'C')
            {
                if (isCover9())
                    return a;
                return b;
            }

            if (c != null)
                return c;
            return new MyCharNotFoundAction();
        }

        /// <summary>
        /// RAW analysion of shape
        /// </summary>
        /// <param name="stroke">raw stroke</param>
        /// <param name="actions">raw action</param>
        /// <returns>raw final action</returns>
        public static bool isItRaw(Stroke stroke, out List<MyAction> actions)
        {
            //if (
            //SupportFunctions.calculateDistance(stroke.StylusPoints.FirstOrDefault(), stroke.StylusPoints.LastOrDefault())
            //    > MyParameters._charMaximumTolerantDistance
            //    )
            //{
            //    actions = null;
            //    return false;
            //}

            //int left = 0;
            //int top = 0;
            //int bottom = 0;
            //int right = 0;

            //for (int i = 0; i < stroke.StylusPoints.Count; i++)
            //{
            //    if (stroke.StylusPoints[i].X > stroke.StylusPoints[right].X)
            //        right = i;

            //    if (stroke.StylusPoints[i].X < stroke.StylusPoints[left].X)
            //        left = i;

            //    if (stroke.StylusPoints[i].Y < stroke.StylusPoints[top].Y)
            //        top = i;

            //    if (stroke.StylusPoints[i].Y > stroke.StylusPoints[bottom].Y)
            //        bottom = i;
            //}

            //int leftFootstep = FootstepRecognition.peekPoint(stroke.StylusPoints[left]);
            //int rightFootstep = FootstepRecognition.peekPoint(stroke.StylusPoints[right]);
            //int topFootstep = FootstepRecognition.peekPoint(stroke.StylusPoints[top]);
            //int bottomFootstep = FootstepRecognition.peekPoint(stroke.StylusPoints[bottom]);

            //if (
            //    (leftFootstep == 0 || leftFootstep == 3 || leftFootstep == 6)
            //    &&
            //    (rightFootstep == 2 || rightFootstep == 5 || rightFootstep == 8)
            //    &&
            //    (topFootstep == 0 || topFootstep == 1 || topFootstep == 2)
            //    &&
            //    (bottomFootstep == 6 || bottomFootstep == 7 || bottomFootstep == 8)
            //    )
            //{
            //    actions = new List<MyAction>() { new MyShowAction('O', null) };
            //    return true;
            //}
            actions = null;
            return false;
        }

        /// <summary>
        /// Raw analysion of cyrcle
        /// </summary>
        /// <param name="cyrcle">given status if cyrcle gesture is colected</param>
        /// <param name="action">0/O decision param based on fraction of heignt and weiht</param>
        /// <returns>action for 0 or O</returns>
        public bool rawAnalysis(bool cyrcle, out List<MyAction> action)
        {
            //if (cyrcle)
            //{
            //    if (SupportFunctions.findIntersect(_myShapeRecognize.getLastStroke()) != null)
            //    {
            //        action = new List<MyAction>() { new MyShowAction('8', null) };
            //        return true;
            //    }
            //}
            action = null;
            return false;
        }
    }
}